package com.fingard.dsp.bank.directbank.bon01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpPortClient;
import com.fingard.net.TcpReceiver;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * TianxingFan/2020/02/10
 */
public class BON01Base extends DirectBase implements ITcpClient {

    //解析响应报文
    protected Map<String, String> parseRespMsg(String[] retStrArr, RetAtsTrans retAts, String actArea) throws Exception {
        Map<String, String> resultMap = new HashMap();
        String tmpRespCode = "";
        String tmpRespInfo = "";
        if (retStrArr[0].length() == 0) {
            StringBuilder curSbMsg = new StringBuilder();
            XmlTextReader curBkReader = loadBankRespXmlReader(retStrArr[1], curSbMsg);
            if (curBkReader != null) {
                String curRetCode = curBkReader.getFirstText("/ap/head/ret_code");
                String curRetInfo = curBkReader.getFirstText("/ap/head/ret_info");
                String curDataMFS = "";
                if ("0000".equals(curRetCode)) {
                    int curRecordNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/record_num"));
                    int curFieldNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/field_num"));
                    if (curRecordNum > 0) {
                        String curFileFlag = curBkReader.getFirstText("/ap/head/file_flag");
                        if ("1".equals(curFileFlag)) {
                            String curFileName = curBkReader.getFirstText("/ap/body/file_name");
                            String curFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + curFileName;
                            WriteBankLogLn("读取前置数据文件：" + curFilePath);
                            curDataMFS = FileHelper.readFileText(curFilePath, getCharset());
                            WriteBankLogStep3(curDataMFS);
                        } else {
                            curDataMFS = curBkReader.getFirstText("/ap/body/serial_record");
                        }
                        if (curDataMFS != null) {
                            StringBuilder curSbLog = new StringBuilder();
                            ArrayList<String[]> curDataList = MFSHelper.getTextArray(curDataMFS, "|", curFieldNum, curRecordNum + 1, curSbLog);
                            if (curSbLog.length() == 0) {
                                //region **字段映射表
                                        /*
                                         0平台流水号（C20）     ｜1账号（C35）           ｜2货币码（C2）    　｜3交易日期（C8）   ｜4交易时间（C6）    ｜
                                         5主机流水号（C20）     ｜6交易行号(C12)         ｜7户名(C70)       　｜8对方账号(C35)    ｜9对方货币码(C2)    ｜
                                         10对方账号户名(C70)    ｜11对方账号开户行(C60)  ｜12对方行号(C12) 　 ｜13交易类别(C1)    ｜14钞汇标志(C1)     ｜
                                         15他行标志(C1)         ｜16同城异地标志(C1)     ｜17手续费(N16.2)    ｜18交易来源(C1)  　｜19发生额标志(C1)   ｜
                                         20被冲销流水号(C12)  　｜21原交易日期(C8)       ｜22现转标志(C1)     ｜23借贷标志(C1)    ｜24交易金额(N16.2)  ｜
                                         25余额(N16.2)          ｜26上笔余额(N16.2)      ｜27冻结金额(N16.2)  ｜28凭证种类(C20)   ｜29凭证批次号(C20)  ｜
                                         30凭证号码(C20)        ｜31交易码(C6)           ｜32柜员号(C10)      ｜33传票号(C20      ｜34摘要(C30)        ｜
                                         35附言(C60)          　｜36交易时间戳           ｜37冲正标志(C1)     ｜38备注字段二(C60　｜
                                         */
                                //endregion
                                for (int i = 1; i < curDataList.size(); i++) {
                                    String[] curRowDataArr = curDataList.get(i);
                                    RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                    tmpRetDetail.actArea = actArea;
                                    tmpRetDetail.actNum = curRowDataArr[1].trim();
                                    tmpRetDetail.recAccNum = curRowDataArr[8].trim();
                                    tmpRetDetail.recAccName = curRowDataArr[10].trim();
                                    tmpRetDetail.recAccBank = StringHelper.convertToDBC(curRowDataArr[11]).trim();
                                    tmpRetDetail.tranDate = curRowDataArr[3].substring(0, 4)
                                            + "-" + curRowDataArr[3].substring(4, 6) + "-" + curRowDataArr[3].substring(6, 8);
                                    tmpRetDetail.tranTime = tmpRetDetail.tranDate + " " +
                                            curRowDataArr[4].substring(0, 2) + ":" + curRowDataArr[4].substring(2, 4) + ":" + curRowDataArr[4].substring(4, 6);
                                    tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                    String cdFlagStr = curRowDataArr[23]; // D 1 表示借 C 2 表示贷
                                    String tranAmtStr = curRowDataArr[24];
                                    if ("C".equals(cdFlagStr)) {
                                        if (tranAmtStr.indexOf("-") >= 0) {
                                            tmpRetDetail.cdFlag = "1";
                                        } else {
                                            tmpRetDetail.cdFlag = "2";
                                        }
                                    } else if ("D".equals(cdFlagStr)) {
                                        if (tranAmtStr.indexOf("-") >= 0) {
                                            tmpRetDetail.cdFlag = "2";
                                        } else {
                                            tmpRetDetail.cdFlag = "1";
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = "借贷标志( " + cdFlagStr + ")无法识别，请与银行核对";
                                        break;
                                    }
                                    tmpRetDetail.tranAmt = curRowDataArr[24].replace("-", "");
                                    tmpRetDetail.accBal = curRowDataArr[25];
                                    tmpRetDetail.postTimestamp = curRowDataArr[36];
                                    tmpRetDetail.billType = curRowDataArr[28];
                                    tmpRetDetail.billNum = curRowDataArr[30];
                                    tmpRetDetail.usage = curRowDataArr[34];
                                    tmpRetDetail.abstr = pickupAbstr(curRowDataArr[35]);
                                    //ATSES-22232 通威目前在用的十个支付渠道,对账码识别截取优化 -----范天星/2020/01/19
                                    String purpose = curRowDataArr[34];
                                    if (purpose.contains("＋")){
                                        tmpRetDetail.abstr = purpose.substring(purpose.lastIndexOf("-") + 1, purpose.length());
                                        tmpRetDetail.usage = purpose.substring(0, purpose.lastIndexOf("-"));
                                    } else {
                                        tmpRetDetail.abstr = "";
                                        tmpRetDetail.usage = curRowDataArr[34];
                                    }
                                    tmpRetDetail.payCode = curRowDataArr[32];
                                    tmpRetDetail.comment = StringHelper.joinNotEmpty(";", curRowDataArr[35], curRowDataArr[38]);
//                                    tmpRetDetail.askNumber = "";
//                                    tmpRetDetail.reqBatchNO = curRowDataArr[29];
                                    tmpRetDetail.cur = this.convertCurToATS(curRowDataArr[2]);
//                                    tmpRetDetail.seqId = "";
//                                    tmpRetDetail.isCollection = "";
                                    tmpRetDetail.originator = curRowDataArr[5];
                                    tmpRetDetail.busType = curRowDataArr[13];
                                    nodeAnalysic(curRowDataArr, tmpRetDetail, getCharset());
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = curSbLog.toString();
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = "数据为空";
                        }
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = curRetInfo;
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = curSbMsg.toString();
            }
        } else {
            tmpRespCode = "-1";
            tmpRespInfo = retStrArr[1];
        }
        resultMap.put("tmpRespCode", tmpRespCode);
        resultMap.put("tmpRespInfo", tmpRespInfo);
        return resultMap;
    }

    protected void writeCommonHeader(XmlTextWriter xmlWriter, BON01Header bon01Header){
        xmlWriter.writeStartDocument();
        xmlWriter.writeStartElement("ap");
        xmlWriter.writeStartElement("head");
        xmlWriter.writeElementString("tr_code", bon01Header.trCode);                                     //交易码
        xmlWriter.writeElementClosed("cms_corp_no");                                                     //银企客户号
        xmlWriter.writeElementClosed("user_no");                                                         //用户号
        xmlWriter.writeElementClosed("org_code");                                                        //机构号
        xmlWriter.writeElementClosed("serial_no");
        xmlWriter.writeElementString("req_no", bon01Header.reqSeqNo);
        if (bon01Header.reqDateTime == null) {
            bon01Header.reqDateTime = new Date();
        }
        xmlWriter.writeElementString("tr_acdt", Format.Date8Format.format(bon01Header.reqDateTime));  //交易日期
        xmlWriter.writeElementString("tr_time", Format.Time6Format.format(bon01Header.reqDateTime));  //交易时间
        xmlWriter.writeElementString("channel", "5");                                          //渠道标识
        xmlWriter.writeElementString("sign", "0");                                              //签名标识
        xmlWriter.writeElementString("file_flag", "0");                                        //文件标识
        xmlWriter.writeElementClosed("reserved");                                                        //保留字段
        xmlWriter.writeEndElement();
    }


    protected String getCharset() {
        return getBankConfig().getCharset("GBK");
    }

    protected String[] sendToBank(String p_reqStr) throws Exception {
        //一：参数、对象定义
        String[] retStrArr = new String[]{"", ""};
        String tmpCharset = getCharset();
        WriteBankLogLn("1.提交银行的地址：" + bankFront.serverIP + ":" + bankFront.serverPort);
        TcpPortClient tmpClient = new TcpPortClient(bankFront.serverIP, Integer.parseInt(bankFront.serverPort), this);

        //二：组织报头
        p_reqStr = "00" + p_reqStr;
        byte[] tmpBytesBody = p_reqStr.getBytes(tmpCharset);
        String tmpHead = String.format("%010d", tmpBytesBody.length);
        byte[] tmpBytesHead = tmpHead.getBytes(tmpCharset);

        //三：封装请求报文：【报头】、【报体】
        byte[] tmpBytesSend = new byte[tmpBytesHead.length + tmpBytesBody.length];
        System.arraycopy(tmpBytesHead, 0, tmpBytesSend, 0, tmpBytesHead.length);
        System.arraycopy(tmpBytesBody, 0, tmpBytesSend, tmpBytesHead.length, tmpBytesBody.length);

        //四：发送报文
        WriteBankLogStep2(tmpHead + p_reqStr);
        TcpReceiver tmpReceiver = tmpClient.sendMessage(tmpBytesSend);
        //五：解析报文
        if (StringHelper.isNullOrEmpty(tmpReceiver.connState)) {
            String tmpBkStr = new String(tmpReceiver.recBytes, 0, tmpReceiver.readedLength, tmpCharset);
            WriteBankLogStep3(tmpBkStr);
        }
        retStrArr[0] = tmpReceiver.connState;
        if (tmpReceiver.isCompleted) {
            retStrArr[1] = new String(tmpReceiver.recBytes, tmpReceiver.contentStartIndex, tmpReceiver.contentLength, tmpCharset);
        } else {
            retStrArr[1] = tmpReceiver.getConnMsg();
            WriteBankLogLn(retStrArr[1]);
        }

        return retStrArr;
    }

    @Override
    public void getContentLength(TcpReceiver tcpReceiver) throws Exception {
        if (tcpReceiver.contentLength == -1) {
            if (tcpReceiver.readedLength >= 12) {
                String tmpHead = new String(tcpReceiver.recBytes, 0, 10, getCharset());
                tcpReceiver.contentLength = Integer.parseInt(tmpHead.trim()) - 2;
                tcpReceiver.contentStartIndex = 12;
            }
        }
    }
}
